﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xpus.Website.Utilities;

namespace Xpus.Website.Data
{
	/// <summary>
	/// 表示内容类型。
	/// </summary>
	public class ContentType
	{
		/// <summary>
		/// 用于存放所有内容类型。
		/// </summary>
		static Dictionary<string, ContentType> _allTypes;

		const string BlogPostTypeName = "BlogPost";
		const string CommentTypeName = "Comment";

		/// <summary>
		/// 表示博客文章。
		/// </summary>
		public static ContentType BlogPost
		{
			get
			{
				return _allTypes[BlogPostTypeName];
			}
		}

		/// <summary>
		/// 表示评论。
		/// </summary>
		public static ContentType Comment
		{
			get
			{
				return _allTypes[CommentTypeName];
			}
		}

		/// <summary>
		/// 初始化内容类型。
		/// </summary>
		static ContentType()
		{
			_allTypes = new Dictionary<string, ContentType>();
			_allTypes.Add(BlogPostTypeName, new ContentType(BlogPostTypeName));
			_allTypes.Add(CommentTypeName, new ContentType(CommentTypeName));
		}

		/// <summary>
		/// 创建具有指定名字的内容类型。
		/// </summary>
		/// <param name="name">内容类型的名字。</param>
		private ContentType(string name)
		{
			this.Name = name;
		}

		/// <summary>
		/// 类型的名字。
		/// </summary>
		public string Name
		{
			get;
			private set;
		}

		/// <summary>
		/// 将内容类型隐式转换为字符串。
		/// </summary>
		/// <param name="type">给定的类型。</param>
		/// <returns>类型的名字。</returns>
		public static implicit operator string(ContentType type)
		{
			return type.Name;
		}

		/// <summary>
		/// 将字符串显式转换为内容类型。
		/// </summary>
		/// <param name="value">内容类型的名字。</param>
		/// <returns>名字所代表的内容类型。</returns>
		public static explicit operator ContentType(string value)
		{
			if(_allTypes.ContainsKey(value))
				return _allTypes[value];
			else
				throw new ArgumentException(string.Format(LanguageUtility.GetString("'{0}' is not a valid content type."), value), "value");
		}

		/// <summary>
		/// 判断一个名字是否为有效的内容类型名字。
		/// </summary>
		/// <param name="value">给定的名字。</param>
		/// <returns>表示是否为有效的内容类型名字。</returns>
		public static bool IsValidValue(string value)
		{
			return _allTypes.ContainsKey(value);
		}
	}

	partial class Content
	{
		#region 字段验证
		/// <summary>
		/// Type属性长度最大值。
		/// </summary>
		public const int TypeMaxLength = 32;

		/// <summary>
		/// Title属性长度最大值。
		/// </summary>
		public const int TitleMaxLength = 1024;

		/// <summary>
		/// Url属性长度最大值。
		/// </summary>
		public const int UrlMaxLength = 1024;

		/// <summary>
		/// FormattedBody属性长度最大值。
		/// </summary>
		public const int FormattedBodyMaxLength = int.MaxValue;

		/// <summary>
		/// PlainBody属性长度最大值。
		/// </summary>
		public const int PlainBodyMaxLength = int.MaxValue;

		/// <summary>
		/// Settings属性长度最大值。
		/// </summary>
		public const int SettingsMaxLength = int.MaxValue;

		partial void OnTypeChanging(string value)
		{
			FieldChecker.CheckFieldNotNull("Type", value);
			FieldChecker.CheckFieldTooLong("Type", value, TypeMaxLength);

			if(!ContentType.IsValidValue(value))
				throw new ArgumentException(
					string.Format(LanguageUtility.GetString("'{0}' is not a valid content type."), value),
					"Type");
		}

		partial void OnTitleChanging(string value)
		{
			FieldChecker.CheckFieldNotNull("Title", value);
			FieldChecker.CheckFieldTooLong("Title", value, TitleMaxLength);
		}

		partial void OnUrlChanging(string value)
		{
			FieldChecker.CheckFieldNotNull("Url", value);
			FieldChecker.CheckFieldTooLong("Url", value, UrlMaxLength);
		}

		partial void OnFormattedBodyChanging(string value)
		{
			FieldChecker.CheckFieldNotNull("FormattedBody", value);
			FieldChecker.CheckFieldTooLong("FormattedBody", value, FormattedBodyMaxLength);
		}

		partial void OnPlainBodyChanging(string value)
		{
			FieldChecker.CheckFieldNotNull("PlainBody", value);
			FieldChecker.CheckFieldTooLong("PlainBody", value, PlainBodyMaxLength);
		}

		partial void OnSettingsChanging(string value)
		{
			FieldChecker.CheckFieldNotNull("Settings", value);
			FieldChecker.CheckFieldTooLong("Settings", value, SettingsMaxLength);
		}
		#endregion

		#region 处理Settings属性
		SettingsUtility _theSettings = new SettingsUtility(string.Empty);

		partial void OnCreated()
		{
			this.Settings = string.Empty;
		}

		partial void OnLoaded()
		{
			_theSettings = new SettingsUtility(this.Settings);
			LoadSettings();
		}

		/// <summary>
		/// 从Settings字段中读取设置。
		/// </summary>
		internal void LoadSettings()
		{
		}

		/// <summary>
		/// 将设置保存到Settings字段中。
		/// </summary>
		internal void SaveSettings()
		{
			this.Settings = _theSettings.ToString();
		}
		#endregion
	}
}
